diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2016-12-13 12:46:09 -0700 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2016-12-13 12:46:09 -0700 |
| commit | 7e0edb6c2db17c87415fbd041ef7add9dfb467e5 (patch) | |
| tree | 2feddf5d1dde80d97b2eefdd299cbebc0d2e30d4 | |
| parent | 5d59aa3e9dffe2912215335ce0b76c67ebbe5a4e (diff) | |
| download | clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.gz clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.bz2 clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.xz clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.zip | |
Corrected negation and single value parse bugs.
Discovered arithmetic bug in the Number class, -4 + 5 is coming back as -1, not 1. It's getting the sign wrong somehow. I'll have to hunt that down.
| -rw-r--r-- | src/lexer.cpp | 12 | ||||
| -rw-r--r-- | src/parser.cpp | 24 | ||||
| -rw-r--r-- | src/scriptengine.cpp | 70 | ||||
| -rw-r--r-- | src/token.cpp | 7 | ||||
| -rw-r--r-- | src/token.h | 10 | ||||
| -rw-r--r-- | src/unitnumber.cpp | 4 |
6 files changed, 83 insertions, 44 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp index 87d603a..9c8b36a 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp | |||
| @@ -96,7 +96,13 @@ Token Lexer::nextTokenNormal() | |||
| 96 | { | 96 | { |
| 97 | sTmp->append( sBuf[iBufPos] ); | 97 | sTmp->append( sBuf[iBufPos] ); |
| 98 | } | 98 | } |
| 99 | return Token( Token::tCommand, sTmp ); | 99 | if( *sTmp == "quit" || *sTmp == "exit" ) |
| 100 | return Token( Token::tCmdExit ); | ||
| 101 | else if( *sTmp == "scale" ) | ||
| 102 | return Token( Token::tCmdScale ); | ||
| 103 | else if( *sTmp == "radix" ) | ||
| 104 | return Token( Token::tCmdRadix ); | ||
| 105 | return Token( Token::tCmdExtended, sTmp ); | ||
| 100 | } | 106 | } |
| 101 | break; | 107 | break; |
| 102 | 108 | ||
| @@ -196,13 +202,13 @@ Token Lexer::nextTokenCommand() | |||
| 196 | if( iBufPos >= sBuf.getSize() ) | 202 | if( iBufPos >= sBuf.getSize() ) |
| 197 | { | 203 | { |
| 198 | iBufPos = -1; | 204 | iBufPos = -1; |
| 199 | return Token( Token::tEndOfLine ); | 205 | return Token( Token::tCmdEndParams ); |
| 200 | } | 206 | } |
| 201 | 207 | ||
| 202 | if( iBufPos < 0 ) | 208 | if( iBufPos < 0 ) |
| 203 | { | 209 | { |
| 204 | if( rIn.isEos() ) | 210 | if( rIn.isEos() ) |
| 205 | return Token( Token::tEndOfInput ); | 211 | return Token( Token::tCmdEndParams ); |
| 206 | 212 | ||
| 207 | sBuf = rIn.readLine(); | 213 | sBuf = rIn.readLine(); |
| 208 | if( sBuf.getSize() == 0 ) | 214 | if( sBuf.getSize() == 0 ) |
diff --git a/src/parser.cpp b/src/parser.cpp index 982c342..8e30d24 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include <bu/sio.h> | 8 | #include <bu/sio.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| 10 | 10 | ||
| 11 | // #define DEBUG_MODE 1 | 11 | //#define DEBUG_MODE 1 |
| 12 | #ifdef DEBUG_MODE | 12 | #ifdef DEBUG_MODE |
| 13 | #define DBG( x ) { x; } (void)0 | 13 | #define DBG( x ) { x; } (void)0 |
| 14 | #else | 14 | #else |
| @@ -161,6 +161,7 @@ void Parser::exprP() | |||
| 161 | return; | 161 | return; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | DBG( Bu::sio << "exprP on " << lex[0] << Bu::sio.nl ); | ||
| 164 | switch( lex[0].eType ) | 165 | switch( lex[0].eType ) |
| 165 | { | 166 | { |
| 166 | case Token::tNumber: | 167 | case Token::tNumber: |
| @@ -188,7 +189,7 @@ void Parser::exprP() | |||
| 188 | case Token::tMinus: | 189 | case Token::tMinus: |
| 189 | lex.nextToken(); | 190 | lex.nextToken(); |
| 190 | exprP(); | 191 | exprP(); |
| 191 | shift( Token( Token::tNegate ) ); | 192 | shift( Token( Token::tNegate ) ); |
| 192 | reduce(); | 193 | reduce(); |
| 193 | break; | 194 | break; |
| 194 | } | 195 | } |
| @@ -196,7 +197,7 @@ void Parser::exprP() | |||
| 196 | 197 | ||
| 197 | void Parser::statement() | 198 | void Parser::statement() |
| 198 | { | 199 | { |
| 199 | if( lex[0].eType == Token::tCommand ) | 200 | if( (lex[0].eType&Token::mMetaCmd) ) |
| 200 | { | 201 | { |
| 201 | lex.setMode( Lexer::modeCommand ); | 202 | lex.setMode( Lexer::modeCommand ); |
| 202 | output( lex[0] ); | 203 | output( lex[0] ); |
| @@ -309,7 +310,8 @@ case Token::tCommand: | |||
| 309 | 310 | ||
| 310 | void Parser::shift( const Token &t ) | 311 | void Parser::shift( const Token &t ) |
| 311 | { | 312 | { |
| 312 | if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) | 313 | if( (t.eType&(Token::mMetaOperator|Token::mMetaAltOp)) || |
| 314 | t.eType==Token::tCloseParen ) | ||
| 313 | tsTerminal.push( t ); | 315 | tsTerminal.push( t ); |
| 314 | else | 316 | else |
| 315 | tsNonTerminal.push( t ); | 317 | tsNonTerminal.push( t ); |
| @@ -317,9 +319,20 @@ void Parser::shift( const Token &t ) | |||
| 317 | 319 | ||
| 318 | void Parser::reduce() | 320 | void Parser::reduce() |
| 319 | { | 321 | { |
| 320 | if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) | 322 | if( tsTerminal.isEmpty() ) |
| 323 | { | ||
| 324 | DBG( Bu::sio << "reduce: terminal stack empty." << Bu::sio.nl ); | ||
| 325 | if( !tsNonTerminal.isEmpty() ) | ||
| 326 | { | ||
| 327 | DBG( Bu::sio << " : non-terminal stack non-empty, pushing item." << Bu::sio.nl ); | ||
| 328 | output( tsNonTerminal.peekPop() ); | ||
| 329 | } | ||
| 330 | return; | ||
| 331 | } | ||
| 332 | if( tsNonTerminal.peek().eType == Token::tOpenParen ) | ||
| 321 | return; | 333 | return; |
| 322 | Token tOp = tsTerminal.peekPop(); | 334 | Token tOp = tsTerminal.peekPop(); |
| 335 | DBG( Bu::sio << "recuding on " << tOp << Bu::sio.nl ); | ||
| 323 | switch( tOp.eType ) | 336 | switch( tOp.eType ) |
| 324 | { | 337 | { |
| 325 | /* | 338 | /* |
| @@ -416,7 +429,6 @@ int Parser::getPriority( Token::Type eType ) | |||
| 416 | { | 429 | { |
| 417 | case Token::tNumber: | 430 | case Token::tNumber: |
| 418 | case Token::tVariable: | 431 | case Token::tVariable: |
| 419 | case Token::tCommand: | ||
| 420 | return 0; | 432 | return 0; |
| 421 | 433 | ||
| 422 | case Token::tPlus: | 434 | case Token::tPlus: |
diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index b65db70..e4c5c2e 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp | |||
| @@ -39,6 +39,12 @@ void ScriptEngine::exec( Expression *pExpr ) | |||
| 39 | 39 | ||
| 40 | for( Expression::iterator i = pExpr->begin(); i; i++ ) | 40 | for( Expression::iterator i = pExpr->begin(); i; i++ ) |
| 41 | { | 41 | { |
| 42 | // Bu::sio << (*i).eType << " - " << sNums << Bu::sio.nl; | ||
| 43 | if( ((*i).eType&Token::mMetaCmd) ) | ||
| 44 | { | ||
| 45 | command( i ); | ||
| 46 | continue; | ||
| 47 | } | ||
| 42 | switch( (*i).eType ) | 48 | switch( (*i).eType ) |
| 43 | { | 49 | { |
| 44 | case Token::tNumber: | 50 | case Token::tNumber: |
| @@ -96,10 +102,6 @@ void ScriptEngine::exec( Expression *pExpr ) | |||
| 96 | case Token::tNegate: | 102 | case Token::tNegate: |
| 97 | sNums.push( -sNums.peekPop() ); | 103 | sNums.push( -sNums.peekPop() ); |
| 98 | break; | 104 | break; |
| 99 | |||
| 100 | case Token::tCommand: | ||
| 101 | command( i ); | ||
| 102 | return; | ||
| 103 | } | 105 | } |
| 104 | } | 106 | } |
| 105 | 107 | ||
| @@ -109,35 +111,39 @@ void ScriptEngine::exec( Expression *pExpr ) | |||
| 109 | 111 | ||
| 110 | void ScriptEngine::command( Expression::iterator &i ) | 112 | void ScriptEngine::command( Expression::iterator &i ) |
| 111 | { | 113 | { |
| 112 | Bu::String sCmd = *(*i).sVal; | 114 | switch( (*i).eType ) |
| 113 | if( sCmd == "exit" || sCmd == "quit" ) | ||
| 114 | { | 115 | { |
| 115 | bRunning = false; | 116 | case Token::tCmdExit: |
| 116 | return; | 117 | bRunning = false; |
| 117 | } | ||
| 118 | else if( sCmd == "scale" ) | ||
| 119 | { | ||
| 120 | if( !(++i) ) | ||
| 121 | { | ||
| 122 | if( sigError.isSet() ) | ||
| 123 | sigError("You must provide a positive integer."); | ||
| 124 | return; | 118 | return; |
| 125 | } | 119 | |
| 126 | int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); | 120 | case Token::tCmdScale: |
| 127 | if( iScale < 0 ) | 121 | { |
| 128 | { | 122 | if( !(++i) ) |
| 129 | if( sigError.isSet() ) | 123 | { |
| 130 | sigError("You must provide a positive integer."); | 124 | if( sigError.isSet() ) |
| 131 | return; | 125 | sigError("You must provide a positive integer."); |
| 132 | } | 126 | return; |
| 133 | if( sigMessage.isSet() ) | 127 | } |
| 134 | sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); | 128 | int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); |
| 135 | for( VarHash::iterator i = hVarState.begin(); i; i++ ) | 129 | if( iScale < 0 ) |
| 136 | (*i).setScale( iScale ); | 130 | { |
| 137 | } | 131 | if( sigError.isSet() ) |
| 138 | else if( sCmd == "radix" ) | 132 | sigError("You must provide a positive integer."); |
| 139 | { | 133 | return; |
| 140 | } | 134 | } |
| 135 | if( sigMessage.isSet() ) | ||
| 136 | sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); | ||
| 137 | for( VarHash::iterator i = hVarState.begin(); i; i++ ) | ||
| 138 | (*i).setScale( iScale ); | ||
| 139 | } | ||
| 140 | break; | ||
| 141 | |||
| 142 | case Token::tCmdRadix: | ||
| 143 | break; | ||
| 144 | |||
| 145 | case Token::tCmdExtended: | ||
| 146 | /* | ||
| 141 | else if( sCmd == "vars" ) | 147 | else if( sCmd == "vars" ) |
| 142 | { | 148 | { |
| 143 | } | 149 | } |
| @@ -146,6 +152,8 @@ void ScriptEngine::command( Expression::iterator &i ) | |||
| 146 | } | 152 | } |
| 147 | else | 153 | else |
| 148 | { | 154 | { |
| 155 | }*/ | ||
| 156 | break; | ||
| 149 | } | 157 | } |
| 150 | } | 158 | } |
| 151 | 159 | ||
diff --git a/src/token.cpp b/src/token.cpp index 0c7bda1..ff04e94 100644 --- a/src/token.cpp +++ b/src/token.cpp | |||
| @@ -45,8 +45,9 @@ Token::~Token() | |||
| 45 | break; | 45 | break; |
| 46 | 46 | ||
| 47 | case tVariable: | 47 | case tVariable: |
| 48 | case tCommand: | ||
| 49 | case tString: | 48 | case tString: |
| 49 | case tCmdExtended: | ||
| 50 | case tCmdParam: | ||
| 50 | delete sVal; | 51 | delete sVal; |
| 51 | break; | 52 | break; |
| 52 | 53 | ||
| @@ -64,8 +65,9 @@ Token &Token::operator=( const Token &rhs ) | |||
| 64 | break; | 65 | break; |
| 65 | 66 | ||
| 66 | case tVariable: | 67 | case tVariable: |
| 67 | case tCommand: | ||
| 68 | case tString: | 68 | case tString: |
| 69 | case tCmdExtended: | ||
| 70 | case tCmdParam: | ||
| 69 | delete sVal; | 71 | delete sVal; |
| 70 | break; | 72 | break; |
| 71 | 73 | ||
| @@ -87,7 +89,6 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) | |||
| 87 | { | 89 | { |
| 88 | case Token::tNumber: return f << "num"; | 90 | case Token::tNumber: return f << "num"; |
| 89 | case Token::tVariable: return f << "var"; | 91 | case Token::tVariable: return f << "var"; |
| 90 | case Token::tCommand: return f << "cmd"; | ||
| 91 | case Token::tPlus: return f << "+"; | 92 | case Token::tPlus: return f << "+"; |
| 92 | case Token::tMinus: return f << "-"; | 93 | case Token::tMinus: return f << "-"; |
| 93 | case Token::tDivide: return f << "/"; | 94 | case Token::tDivide: return f << "/"; |
diff --git a/src/token.h b/src/token.h index 5bede41..4d738ec 100644 --- a/src/token.h +++ b/src/token.h | |||
| @@ -15,7 +15,7 @@ public: | |||
| 15 | { | 15 | { |
| 16 | tNumber = 0x1001, | 16 | tNumber = 0x1001, |
| 17 | tVariable = 0x2002, | 17 | tVariable = 0x2002, |
| 18 | tCommand = 0x2003, | 18 | //tCommand = 0x2003, |
| 19 | tPlus = 0x4004, | 19 | tPlus = 0x4004, |
| 20 | tMinus = 0x4005, | 20 | tMinus = 0x4005, |
| 21 | tDivide = 0x4006, | 21 | tDivide = 0x4006, |
| @@ -34,12 +34,20 @@ public: | |||
| 34 | tUninitialized = 0x0110, | 34 | tUninitialized = 0x0110, |
| 35 | tComputedValue = 0x0111, | 35 | tComputedValue = 0x0111, |
| 36 | 36 | ||
| 37 | tCmdExit = 0x0201, | ||
| 38 | tCmdScale = 0x0202, | ||
| 39 | tCmdRadix = 0x0203, | ||
| 40 | tCmdExtended = 0x02f0, | ||
| 41 | tCmdParam = 0x02f1, | ||
| 42 | tCmdEndParams = 0x02f2, | ||
| 43 | |||
| 37 | 44 | ||
| 38 | mMetaNumber = 0x1000, | 45 | mMetaNumber = 0x1000, |
| 39 | mMetaString = 0x2000, | 46 | mMetaString = 0x2000, |
| 40 | mMetaOperator = 0x4000, | 47 | mMetaOperator = 0x4000, |
| 41 | mMetaAltOp = 0x8000, | 48 | mMetaAltOp = 0x8000, |
| 42 | mMetaMeta = 0x0100, | 49 | mMetaMeta = 0x0100, |
| 50 | mMetaCmd = 0x0200 | ||
| 43 | }; | 51 | }; |
| 44 | 52 | ||
| 45 | Token(); | 53 | Token(); |
diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp index d213ed7..c316d4b 100644 --- a/src/unitnumber.cpp +++ b/src/unitnumber.cpp | |||
| @@ -89,6 +89,10 @@ void UnitNumber::number1() | |||
| 89 | mathTest("1000902491523000321", *, "3004392012498000700", | 89 | mathTest("1000902491523000321", *, "3004392012498000700", |
| 90 | "3007103450821050020096034077958224700"); | 90 | "3007103450821050020096034077958224700"); |
| 91 | 91 | ||
| 92 | mathTest("-4", -, "5", "-9"); | ||
| 93 | mathTest("-4", -, "-5", "1"); | ||
| 94 | mathTest("-4", +, "5", "1"); | ||
| 95 | mathTest("5", +, "-4", "1"); | ||
| 92 | mathTest("-872", +, "123", "-749"); | 96 | mathTest("-872", +, "123", "-749"); |
| 93 | mathTest("728", +, "-51", "677"); | 97 | mathTest("728", +, "-51", "677"); |
| 94 | mathTest("44", +, "-55", "-11"); | 98 | mathTest("44", +, "-55", "-11"); |
